SocksServerHandler{ }
toHexString{
  StringBuffer out=new StringBuffer(blob.length * 2 + 1);
}
messageReceived{
  ChannelBuffer msg=(ChannelBuffer)e.getMessage();
  msg=msg.slice(msg.readerIndex(),msg.writerIndex());
    if (outboundChannel.isWritable()) {
      trafficLogger.log(connectionId,"send",num.incrementAndGet(),msg.array());
      Channels.write(outboundChannel,msg);
      e.getChannel().setReadable(false);
    return;
  if (socksProtocol == null) {
    try {
      socksProtocol=SocksProtocols.create(msg);
      Channels.close(e.getChannel());
      return;
  try {
    socksProtocol.processMessage(msg);
    Channels.close(e.getChannel());
    return;
  if (socksProtocol instanceof Socks5Protocol) {
    Socks5Protocol s5=(Socks5Protocol)socksProtocol;
    isBind=s5.isBIND();
    isConnect=s5.isCONNECT();
  if (isConnect && socksProtocol.isReady()) {
    final InetSocketAddress outboundAddress=socksProtocol.getOutboundAddress();
    System.out.println("Connect " + outboundAddress);
    final Channel inboundChannel=e.getChannel();
    inboundChannel.setReadable(false);
    ClientBootstrap outboundClientBootstrap=new ClientBootstrap(clientFactory);
    ChannelFuture outboundClientFuture=outboundClientBootstrap.connect(outboundAddress);
    outboundClientFuture.addListener(new ChannelFutureListener(){
      @Override public void operationComplete(      ChannelFuture outboundClientFuture) throws Exception {
        if (outboundClientFuture.isSuccess()) {
          outboundChannel=outboundClientFuture.getChannel();
          socksProtocol.setConnected(true);
          if (socksProtocol.hasResponse()) {
            byte[] res=socksProtocol.getResponse();
            write(inboundChannel,ChannelBuffers.wrappedBuffer(res));
          socksProtocol.setConnected(false);
          if (socksProtocol.hasResponse() && inboundChannel.isWritable()) {
            Channels.write(inboundChannel,ChannelBuffers.wrappedBuffer(socksProtocol.getResponse())).addListener(ChannelFutureListener.CLOSE);
 else   if (socksProtocol.hasResponse()) {
    write(e.getChannel(),ChannelBuffers.wrappedBuffer(socksProtocol.getResponse()));
}
operationComplete{
  if (outboundClientFuture.isSuccess()) {
    outboundChannel=outboundClientFuture.getChannel();
    inboundChannel.setReadable(true);
    socksProtocol.setConnected(true);
    if (socksProtocol.hasResponse()) {
      byte[] res=socksProtocol.getResponse();
      write(inboundChannel,ChannelBuffers.wrappedBuffer(res));
    socksProtocol.setConnected(false);
    if (socksProtocol.hasResponse() && inboundChannel.isWritable()) {
      Channels.write(inboundChannel,ChannelBuffers.wrappedBuffer(socksProtocol.getResponse())).addListener(ChannelFutureListener.CLOSE);
}
channelClosed{
  closeOnFlush(e.getChannel());
}
exceptionCaught{
  System.out.println("C");
  Channels.close(e.getChannel());
    Channels.close(outboundChannel);
}
closeOnFlush{
  if (ch.isConnected()) {
    ch.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
write{
  if (ch.isWritable()) {
    ch.write(msg);
 else {
    ch.setReadable(false);
}
